package animator.phantom.renderer;

/*
    Copyright Janne Liljeblad

    This file is part of Phantom2D.

    Phantom2D is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Phantom2D is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Phantom2D.  If not, see <http://www.gnu.org/licenses/>.
*/

import animator.phantom.renderer.param.*;
import org.w3c.dom.*;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.util.XMLResourceDescriptor;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.transcoder.*;
import org.apache.batik.dom.util.DOMUtilities;
import org.w3c.dom.svg.SVGDocument;
import giotto2D.core.GeometricFunctions;
import java.awt.geom.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.swing.ImageIcon;
import animator.phantom.gui.*;
import java.util.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;

//--- Used to get images from SVG files.
public class SVGSource extends FileSource
{
	private Document doc;
	private Element svgRoot;
	private long docSize;

	private static final String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
	private static final DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();

	//--- file type icon
	private static ImageIcon svgIcon = GUIResources.getIcon( GUIResources.svgicon );

	//--- Dummy for loading.
	public SVGSource(){}

	//----------------------------------------- CONSTRUCTOR
	public SVGSource( File  f )
	{
		this.file = f;
		type = SVG_FILE;
	}
	//--- Loads image and and remembers its size.
	public void firstLoadData()
	{
 		loadData();
		sizeEstimate = file.length();
	}

	public void clearData()
	{
		doc = null;
	}

	//--- Load and build doc.
	public void loadData()
	{
		if( doc == null )
		{
			try 
			{
				String parser = XMLResourceDescriptor.getXMLParserClassName();
				SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
				doc = f.createSVGDocument(file.toURI().toString());
				svgRoot = doc.getDocumentElement();
				String wString = svgRoot.getAttribute( "width" );
				String hString = svgRoot.getAttribute( "height" );
				imgWidth = Integer.parseInt( getIntPart( wString ) );
				imgHeight = Integer.parseInt( getIntPart( hString ) );
			} 
			catch (IOException ex) 
			{
				hasResourceAvailable = false;
				System.out.println( ex.getMessage() );
				System.out.println( "SVGDocument creationFailed in SVGSource" );
			}
		}
		else
		{
			System.out.println("tried to load svgdoc when already loaded" );
		}
	}

	//--- Cuts decimal part from number string
	private String getIntPart( String numString )
	{
		int dot = numString.indexOf( "." );
		if( dot == -1 ) return numString;
		else return numString.substring( 0, dot );
	}

	public boolean dataInMemory(){ return ( doc != null ); }

	public BufferedImage getBufferedImage()
	{
		return getImageFromDocument();
	}

	//--- Used when doing memory management and in<che flag has just been set.
	public void cacheOrClearData()
	{
		if( inCache )
		{
			if( doc == null )loadData();
		}
		else doc = null;
	}

	public BufferedImage getImageFromDocument()
	{
		if( doc == null ) loadData();

		return getImageFromDocumentObject( doc );
	}

	private BufferedImage getImageFromDocumentObject( Document drawDoc )
	{
		SVGToBufferedImageTranscoder t = new SVGToBufferedImageTranscoder();
		TranscoderInput input = new TranscoderInput( drawDoc );

		try
		{
			t.transcode( input, null );
		}
		catch( Exception e )
		{
			System.out.println( e.getStackTrace() );
		}
		return t.getBufferedImage();
	}

	public ImageIcon getThumbnailIcon()
	{
		if( !fileAvailable() ) return noFileIcon;
		return GUIUtils.getThumbnailFromImage( getImageFromDocument(), BinsAreaPanel.ICON_WIDTH, BinsAreaPanel.ICON_HEIGHT );
	}

	public ImageIcon getFileTypeIcon()
	{
		return svgIcon;
	}

	//---------------------------------------------------------------------------- Continuous render support
	public BufferedImage getTranslatedImageFromDocument( 	float frameTime,
								AnimatedImageCoordinates coords,
								Dimension screenSize,
								boolean flipH,
								boolean flipV )
	{
		if( doc == null ) 
			loadData();

		SVGDocumentTransformer tform = new SVGDocumentTransformer( doc );
		tform.setTransform(	frameTime,
					coords,
					screenSize,
					flipH,
					flipV );
		tform.transform();
		//writeXmlFile( tform.getTransformedDocument(), "/home/janne/" + file.getName() );
		return getImageFromDocumentObject( tform.getTransformedDocument() );
	}

	private static void writeXmlFile(Document doc, String filename) 
	{
		try 
		{
			// Prepare the DOM document for writing
			Source source = new DOMSource(doc);

			// Prepare the output file
			File file = new File(filename);
			Result result = new StreamResult(file);

			// Write the DOM document to the file
			Transformer xformer = TransformerFactory.newInstance().newTransformer();
			xformer.transform(source, result);
		} 
		catch (TransformerConfigurationException e){} 
		catch (TransformerException e){}
	}

}//end class
